<template>
    <u--form class="form" ref="uForm" v-bind="formOptions">
        <u-form-item class="form-item" v-for="(item, index) in props.items" :key="index" :label="item.label"
            :prop="item.key" :required="props.rules[item.key] && props.rules[item.key].required"
            :borderBottom="attrs.borderBottom">
            <!-- 文字 -->
            <u--input class="form-item-body" v-if="item.type == 'text'" v-model="formDataCache[item.key]" type="text"
                :placeholder="item.placeholder || `请输入${item.label}`" :disabled="item.disabled" inputAlign="right"
                border="none"></u--input>
            <!-- 数字 -->
            <u--input class="form-item-body" v-else-if="item.type == 'number'" v-model="formDataCache[item.key]"
                type="number" :placeholder="item.placeholder || `请输入${item.label}`" :disabled="item.disabled"
                inputAlign="right" border="none"></u--input>
            <!-- 带小数点数字 -->
            <u--input class="form-item-body" v-else-if="item.type == 'digit'" v-model="formDataCache[item.key]" type="digit"
                :placeholder="item.placeholder || `请输入${item.label}`" :disabled="item.disabled" inputAlign="right"
                border="none"></u--input>
            <!-- 密码 -->
            <u--input class="form-item-body" v-else-if="item.type == 'password'" v-model="formDataCache[item.key]"
                type="password" :placeholder="item.placeholder || `请输入${item.label}`" :disabled="item.disabled"
                inputAlign="right" border="none"></u--input>
            <!-- 身份证 -->
            <u--input class="form-item-body" v-else-if="item.type == 'idcard'" v-model="formDataCache[item.key]"
                type="idcard" :placeholder="item.placeholder || `请输入${item.label}`" :disabled="item.disabled"
                inputAlign="right" border="none"></u--input>
            <!-- 文本域 -->
            <u--textarea class="form-item-body" v-else-if="item.type == 'textarea'" v-model="formDataCache[item.key]"
                :placeholder="item.placeholder || `请输入${item.label}`" :disabled="item.disabled" :maxlength="item.maxlength"
                :count="Boolean(item.maxlength)" border="none" placeholderStyle="text-align: right;"></u--textarea>
            <!-- 滚动选择器 -->
            <template v-else-if="item.type == 'select'">
                <u-cell class="form-item-body" title=""
                    :value="item.items.find(i => i.key == formDataCache[item.key])?.label || (item.placeholder || `请选择${item.label}`)"
                    :border="false" isLink :disabled="item.disabled" @click="() => item.show = true">
                </u-cell>
                <u-picker :show="item.show" keyName="label" :columns="Array(item.items)" :itemHeight="attrs.itemHeight"
                    :visibleItemCount="attrs.visibleItemCount" :showToolbar="false" :closeOnClickOverlay="true"
                    :immediateChange="true" @close="() => item.show = false"
                    @change="({ index }) => selectChangeHandler(index, item)">
                </u-picker>
            </template>
            <!-- 开关 -->
            <u-switch class="form-item-body" v-else-if="item.type == 'switch'" v-model="formDataCache[item.key]"
                :disabled="item.disabled"></u-switch>
            <!-- 单选 -->
            <u-radio-group class="form-item-body" v-else-if="item.type == 'radio'" v-model="formDataCache[item.key]"
                :disabled="item.disabled" :shape="item.shape || 'circle'" :placement="item.placement || 'column'">
                <u-radio v-for="(item, index) in item.items" :key="index" :label="item.label" :name="item.key">
                </u-radio>
            </u-radio-group>
            <!-- 多选 -->
            <u-checkbox-group class="form-item-body" v-else-if="item.type == 'checkbox'" v-model="formDataCache[item.key]"
                :disabled="item.disabled" :placement="item.placement || 'column'">
                <u-checkbox v-for="(item, index) in item.items" :key="index" :label="item.label" :name="item.key">
                </u-checkbox>
            </u-checkbox-group>
            <!-- 滑动取值 -->
            <u-slider class="form-item-body" v-else-if="item.type == 'slider'" v-model="formDataCache[item.key]"
                :disabled="item.disabled" :step="item.step" :min="item.min" :max="item.max" :showValue="true"></u-slider>
            <!-- 评分 -->
            <u-rate v-else-if="item.type == 'rate'" size="large" v-model="formDataCache[item.key]" :count="5"
                :disabled="item.disabled" style="text-align: right;"></u-rate>
            <!-- 时间选择器datetime -->
            <template v-else-if="item.type == 'datetime'">
                <u-cell class="form-item-body" title=""
                    :value="formDataCache[item.key] || (item.placeholder || `请选择${item.label}`)" :border="false" isLink
                    :disabled="item.disabled" @click="() => item.show = true">
                </u-cell>
                <u-datetime-picker :show="item.show" v-model="formDataCache[item.key]" mode="datetime"
                    :itemHeight="attrs.itemHeight" :visibleItemCount="attrs.visibleItemCount" :showToolbar="false"
                    :closeOnClickOverlay="true" @close="() => item.show = false"
                    @change="({ value }) => timeChangeHandler(value, item)">
                </u-datetime-picker>
            </template>
            <!-- 时间选择器time -->
            <template v-else-if="item.type == 'time'">
                <u-cell class="form-item-body" title=""
                    :value="formDataCache[item.key] || (item.placeholder || `请选择${item.label}`)" :border="false" isLink
                    :disabled="item.disabled" @click="() => item.show = true">
                </u-cell>
                <u-datetime-picker :show="item.show" v-model="formDataCache[item.key]" mode="time"
                    :itemHeight="attrs.itemHeight" :visibleItemCount="attrs.visibleItemCount" :showToolbar="false"
                    :closeOnClickOverlay="true" @close="() => item.show = false"
                    @change="({ value }) => timeChangeHandler(value, item)">
                </u-datetime-picker>
            </template>
            <!-- 时间选择器date -->
            <template v-else-if="item.type == 'date'">
                <u-cell class="form-item-body" title=""
                    :value="formDataCache[item.key] || (item.placeholder || `请选择${item.label}`)" :border="false" isLink
                    :disabled="item.disabled" @click="() => item.show = true">
                </u-cell>
                <up-calendar :show="item.show" :defaultDate="formDataCache[item.key]" mode="single" :show-confirm="false"
                    :showTitle="false" :closeable="false" :closeOnClickOverlay="true"
                    @confirm="value => dateChangeHandler(value, item)" @close="() => item.show = false"></up-calendar>
            </template>
            <!-- 时间选择器dates -->
            <template v-else-if="item.type == 'dates'">
                <u-cell class="form-item-body" title=""
                    :value="(formDataCache[item.key] && formDataCache[item.key].join('、')) || (item.placeholder || `请选择${item.label}`)"
                    :border="false" isLink :disabled="item.disabled" @click="() => item.show = true">
                </u-cell>
                <up-calendar :show="item.show" :defaultDate="formDataCache[item.key]" mode="multiple" :show-confirm="false"
                    :showTitle="false" :closeable="false" :closeOnClickOverlay="true"
                    @confirm="value => dateChangeHandler(value, item)" @close="() => item.show = false"></up-calendar>
            </template>
            <!-- 时间选择器daterange -->
            <template v-else-if="item.type == 'daterange'">
                <u-cell class="form-item-body" title=""
                    :value="(formDataCache[item.key] && formDataCache[item.key][0] ? `${formDataCache[item.key][0]} 至 ${formDataCache[item.key][formDataCache[item.key].length - 1]}` : false) || (item.placeholder || `请选择${item.label}`)"
                    :border="false" isLink :disabled="item.disabled" @click="() => item.show = true">
                </u-cell>
                <up-calendar :show="item.show" :defaultDate="formDataCache[item.key]" mode="range" startText="" endText=""
                    :show-confirm="false" :showTitle="false" :closeable="false" :closeOnClickOverlay="true"
                    @confirm="value => dateChangeHandler(value, item)" @close="() => item.show = false"></up-calendar>
            </template>
            <!-- 验证码 -->
            <template v-else-if="item.type == 'code'">
                <u-code-input class="form-item-body" v-model="formDataCache[item.key]" mode="line" hairline
                    :disabledKeyboard="item.disabled" maxlength="4">
                </u-code-input>
                <u-button style="margin-left: 10px;" v-if="item.url" type="primary" size="small"
                    :disabled="item.disabled || codeSeconds != 0" @tap="getCode(item.url, item.timer)">
                    {{ codeTips }}
                </u-button>
            </template>
            <!-- 地址 -->
            <template v-else-if="item.type == 'address'">
                <u-cell class="form-item-body" title=""
                    :value="formDataCache[item.key] && (formDataCache[item.key].name || formDataCache[item.key].address) || (item.placeholder || `请选择${item.label}`)"
                    :border="false" isLink :disabled="item.disabled" @click="chooseAddress()">
                </u-cell>
            </template>
            <!-- 自定义 -->
            <template v-else-if="item.type == 'slot'">
                <slot :name="item.slotName"></slot>
            </template>
        </u-form-item>
    </u--form>
</template>

<script setup>
const uForm = ref()
const props = defineProps({
    data: {
        type: Object,
        require: true
    },
    items: {
        type: Array,
        require: true
    },
    rules: {
        type: Object,
    },
})
const emit = defineEmits(["update:data"])
defineExpose({ $form: uForm })
const attrs = reactive({
    borderBottom: true, // 显示表单域的下划线边框
    itemHeight: 100, // 选择器单个选项的高度
    visibleItemCount: 5, // 选择器可见选项的数量
})
const formDataCache = ref({})
const formOptions = computed(() => {
    // 配置入参和自定义校验规则 https://element-plus.org/zh-CN/component/form.html
    return {
        labelPosition: 'left',
        labelWidth: 'auto',
        model: formDataCache.value,
        rules: props.rules,
    }
})
const selectChangeHandler = (index, item) => {
    const { items, key } = item
    formDataCache.value[key] = items[index].key
}
const timeChangeHandler = (time, item) => {
    const { type, key } = item
    const formatter = type == 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : type == 'date' ? 'YYYY-MM-DD' : undefined
    formDataCache.value[key] = formatter ? $dayjs(time).format(formatter) : time
}
const dateChangeHandler = (time, item) => {
    const { type, key } = item
    formDataCache.value[key] = type == 'date' ? time[0] : type == 'dates' ? toRaw(time) : type == 'daterange' ? toRaw(time) : time[0]
}
const codeSeconds = ref(0)
const codeTips = computed(() => {
    if (codeSeconds.value == 0) {
        return '获取'
    } else {
        return codeSeconds.value + '秒'
    }
})
const getCode = (url, timer) => {
    codeSeconds.value = timer
    const interval = setInterval(() => {
        codeSeconds.value--
        if (codeSeconds.value == 0) {
            clearInterval(interval)
        }
    }, 1000)
    $post(url).then(res => {
        console.log(res);
    })
}
const chooseAddress = () => {
    uni.chooseLocation({
        success: ({ name, address, longitude, latitude }) => {
            formDataCache.value[key] = {
                name,
                address,
                lng: longitude,
                lat: latitude
            }
        },
        fail: (error) => { }
    })
}
const checkAttrs = (type) => {
    switch (type) {
        case 'required':

            break;
        case 'required':

            break;
    }
}
watch(formDataCache, data => {
    emit("update:data", toRaw(data))
}, {
    deep: true
})

// onCreated初始化数据到表单缓存中
formDataCache.value = props.data
</script>

<style lang="scss" scoped>
.form {
    width: 95%;

    .form-item {
        .form-item-body {
            width: 100%;
            justify-content: flex-end;
        }

        :deep(.u-cell__body) {
            padding: 0;
        }

        :deep(.u-form-item__body__right__content__slot) {
            justify-content: flex-end;
        }

        :deep(.uni-textarea-textarea) {
            text-align: right;
        }

        :deep(.u-radio) {
            justify-content: flex-end;
        }

        :deep(.u-checkbox) {
            justify-content: flex-end;
        }

        :deep(uni-slider) {
            margin-right: 0;

            :deep(.uni-slider-value) {
                width: auto;
            }
        }
    }
}
</style>
